package cn.techwis.service;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.techwis.common.WxApi;
import cn.techwis.common.WxPayTypeEnum;
import cn.techwis.util.PayOrderSignUtil;
import cn.techwis.vo.EntrancePayVO;
import cn.techwis.vo.InItVO;
import cn.techwis.vo.PayOrderVO;
import cn.techwis.util.WxHttpUtil;


import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;

import static cn.techwis.common.WxPayTypeEnum.*;

/**
 * 通用支付 service
 */
public class PayOrderService extends Tservice {


    /**
     * 通用下单接口
     *
     * @param entrancePayVO
     * @return
     */
    public static final String entrancePay(EntrancePayVO entrancePayVO, InItVO inItVO) {
        validateObject(entrancePayVO, EntrancePayVO.EntrancePay.class, inItVO);
        WxPayTypeEnum wxPayTypeEnum = entrancePayVO.getWxPayTypeEnum();
        if (wxPayTypeEnum.equals(JSAPI)) {
            return jsapiPay(entrancePayVO.getPayOrderVO(), inItVO);
        } else if (wxPayTypeEnum.equals(APP)) {
            return appPay(entrancePayVO.getPayOrderVO(), inItVO);
        } else if (wxPayTypeEnum.equals(MWEB)) {
            return h5Pay(entrancePayVO.getPayOrderVO(), inItVO);
        } else if (wxPayTypeEnum.equals(NATIVE)) {
            return nativePay(entrancePayVO.getPayOrderVO(), inItVO);
        } else {
            throw ExceptionUtil.wrapRuntime("未知的下单类型");
        }
    }


    /**
     * 小程序支付/jsapi 支付
     *
     * @param payOrderVO 实体对象
     */
    public static final String jsapiPay(PayOrderVO payOrderVO, InItVO inItVO) {
        validateObject(payOrderVO, PayOrderVO.JsapiPay.class, inItVO);
        JSONObject jsonObject = WxHttpUtil.requestPost("小程序/JSAPI支付", WxApi.payAppi.JSAPI, payOrderVO, inItVO.getPrivateKeyFileName(), payOrderVO.getMchid(), inItVO.getSerialNo());
        return payResult(jsonObject);
    }

    /**
     * app下单支付
     *
     * @param payOrderVO 实体对象
     * @return
     */
    public static final String appPay(PayOrderVO payOrderVO, InItVO inItVO) {
        validateObject(payOrderVO, PayOrderVO.AppPay.class, inItVO);
        JSONObject jsonObject = WxHttpUtil.requestPost("APP支付", WxApi.payAppi.APPAPI, payOrderVO, inItVO.getPrivateKeyFileName(), payOrderVO.getMchid(), inItVO.getSerialNo());
        return payResult(jsonObject);
    }

    /**
     * H5
     *
     * @param payOrderVO 实体对象
     * @return
     */
    public static final String h5Pay(PayOrderVO payOrderVO, InItVO inItVO) {
        validateObject(payOrderVO, PayOrderVO.H5Pay.class, inItVO);
        JSONObject jsonObject = WxHttpUtil.requestPost("H5支付", WxApi.payAppi.H5API, payOrderVO, inItVO.getPrivateKeyFileName(), payOrderVO.getMchid(), inItVO.getSerialNo());
        return payH5Result(jsonObject);
    }

    /**
     * Native
     *
     * @param payOrderVO 实体对象
     * @return
     */
    public static final String nativePay(PayOrderVO payOrderVO, InItVO inItVO) {
        validateObject(payOrderVO, PayOrderVO.H5Pay.class, inItVO);
        JSONObject jsonObject = WxHttpUtil.requestPost("Native支付", WxApi.payAppi.NATIVEAPI, payOrderVO, inItVO.getPrivateKeyFileName(), payOrderVO.getMchid(), inItVO.getSerialNo());
        return payNativeResult(jsonObject);
    }

 /**
     * @Author yandong
     * @Description 封装微信公众吊起支付所需参数
     * @Date 2021/5/26
     * @Param
     * @Return
     * @MethodName
     **/
    public static final JSONObject paymentAction(String appId, String prepay_id, String privateKeyFileName) throws Exception {
        //获取当前时间
        long time = DateUtil.current() / 1000;
        //生成随机字符串
        String randomString = RandomUtil.randomString(32);
        StringBuilder stringBuilder = StrUtil.builder()
                .append(appId).append("\n")
                .append(time).append("\n")
                .append(randomString).append("\n")
                .append("prepay_id=").append(prepay_id).append("\n");
        String sign = PayOrderSignUtil.sign(stringBuilder.toString().getBytes(), privateKeyFileName);
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOpt("appId", appId);
        jsonObject.putOpt("timeStamp", time);
        jsonObject.putOpt("nonceStr", randomString);
        jsonObject.putOpt("package", "prepay_id=" + prepay_id);
        jsonObject.putOpt("packageValue", "prepay_id=" + prepay_id);
        jsonObject.putOpt("signType", "RSA");
        jsonObject.putOpt("paySign", sign);
        return jsonObject;
    }


    /**
     * @Author yandong
     * @Description 封装微信app起支付所需参数
     * @Date 2021/5/26
     * @Param
     * @Return
     * @MethodName
     **/
    public static final JSONObject paymentApp(String appId, String prepay_id, String privateKeyFileName, String mchId) throws Exception {
        //获取当前时间
        long time = DateUtil.current() / 1000;
        //生成随机字符串
        String randomString = RandomUtil.randomString(32);
        StringBuilder stringBuilder = StrUtil.builder()
                .append(appId).append("\n")
                .append(time).append("\n")
                .append(randomString).append("\n")
                .append(prepay_id).append("\n");


        log.info("签名的数据->{}",stringBuilder.toString());
        String sign = PayOrderSignUtil.sign(stringBuilder.toString().getBytes(CharsetUtil.UTF_8), privateKeyFileName);
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOpt("appid", appId);
        jsonObject.putOpt("timestamp", time);
        jsonObject.putOpt("nonceStr", randomString);
        jsonObject.putOpt("packageValue", "Sign=WXPay");
        jsonObject.putOpt("package", "Sign=WXPay");
        jsonObject.putOpt("sign", sign);
        //app支付
        jsonObject.putOpt("partnerid", mchId);
        jsonObject.putOpt("prepayId",prepay_id);
        return jsonObject;
    }

    public static void main(String[] args) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, SignatureException, NoSuchProviderException, InvalidKeyException, IOException {
        PayOrderVO payOrderVO = new PayOrderVO();
        payOrderVO.setAppid("wxa324e2f834527e8a");
        payOrderVO.setMchid("1505026761");
        payOrderVO.setDescription("描述");
        payOrderVO.setOut_trade_no("12177525012014070332333680111111");
        payOrderVO.setNotify_url("https://www.biimai.cn/qinyunMallServer/orderNotify/payOrderAsyncNotice");
        payOrderVO.setAmount(PayOrderVO.AmountVO.builder().total(1).currency("CNY").build());
        payOrderVO.setPayer(PayOrderVO.PayerVO.builder().openid("oQGk85L5JOE1w__RdtYHq8yqwakk").build());
        EntrancePayVO entrancePayVO = new EntrancePayVO();
        entrancePayVO.setPayOrderVO(payOrderVO);
        entrancePayVO.setWxPayTypeEnum(JSAPI);
        InItVO inItVO = new InItVO();
        inItVO.setPrivateKeyFileName("C:\\Users\\yando\\Desktop\\apiclient_key.pem");
        inItVO.setSerialNo("71B1200AE00607AA44A2EC99DB14387CF266C354");
        inItVO.setMchId("1505026761");
        String entrancePay = entrancePay(entrancePayVO, inItVO);
        paymentAction(payOrderVO.getAppid(), entrancePay, inItVO.getPrivateKeyFileName());
    }

}
